Are you my “neighbours”?

One of the analyses in geospatial is to find out how strong is the spatial relationship between different interest objects.
This is an important step before we could perform spatial autocorrelation.
But how do we know who are the “neighbours”?
Sometimes it can be not very obvious from the map.

Generated from Imgflip
This is where we will use spatial weighting method to find the list of neighbours.
In this post, we will focus on one of the spatial weighting methods, which is contiguity-based spatial weights.
Contiguity means that two spatial units share a common border of non-zero length (Anselin 2020).
In other words, we are interested in finding whether the two areas “touch” each other.
There are two types of contiguity-based spatial weights.
They are queen contiguity and rook contiguity.
As the names suggested, the definition of “neighbours” under each method matches the respective movements on the chess board.
Below is the illustration of the definition of “neighbours” under each method:

Taken from (De Bellefon, Loonis, and Le Gleut 2018)
There are different spatial weighting techniques.
Then how would we know which one is more appropriate since different spatial weighting might give us different results?
(Kam 2020) discussed the considerations in one of his lectures.
In summary, below are different spatial weighting methods and when they are more appropriate:
Polygon contiguity
Fixed distance method
Work well for point data
Alternative for polygon data when there is a large variation in polygon size
Inverse distance method
k-nearest neighbours method
I will cover the other weighting methods in my future post.
I will download Malaysia shape files from this link.
For more explanations on shape files, please refer to my previous post.
First, I will set up the environment by calling the necessary packages.
pacman::p_load(tidyverse, sf, spdep, tmap, janitor)
I will also set the tmap_mode to view so that I can interact with the graphs.
tmap_mode('view')
Next, I will import the dataset into the environment.
msia_map <- st_read(dsn = "data", layer = "MYS_adm2")
Reading layer `MYS_adm2' from data source
`C:\Users\jaspe\OneDrive\Documents\2_Data Science\98_my-blog\_posts\2023-02-05-contiguity-spatial-weights\data'
using driver `ESRI Shapefile'
Simple feature collection with 144 features and 14 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 99.64072 ymin: 0.855001 xmax: 119.2697 ymax: 7.380556
Geodetic CRS: WGS 84
Next, I will visualize the Malaysia map.
tm_shape(msia_map) +
tm_polygons()
Good! Now, we can proceed and find the “neighbours”.
In this sub-section, I will derive the contiguity-based spatial weights.
To better visualize the spatial weights results later, I will find the centroids of different administrative districts.
longitude <- map_dbl(msia_map$geometry, ~st_centroid(.x)[[1]])
latitude <- map_dbl(msia_map$geometry, ~st_centroid(.x)[[2]])
Once the latitude and longitude are derived, I will use cbind function to bind the columns together.
coords <- cbind(longitude, latitude)
I will use poly2nb function and pass TRUE to queen argument to derive the queen contiguity based neighbours.
Note that the queen argument is TRUE by default.
msia_map_queen <-
poly2nb(msia_map, queen = TRUE)
To visualize the results, I will do the following:
Plot an empty Malaysia map
Then, plot the graphs on queen contiguity based neighbours
plot(msia_map$geometry,
border="lightgrey",
main="Queen Contiguity-based Neighbours")
plot(msia_map_queen,
coords,
pch = 20,
cex = 0.5,
add = TRUE,
col= "blue")

Remember to indicate the add argument should be TRUE, otherwise the code will return the neighbours map without the underlying Malaysia map.
To derive Rook contiguity-based neighbours, I will still use ploy2nb function and specify FALSE for the queen argument.
msia_map_rook <-
poly2nb(msia_map, queen = FALSE)
Similarly, to visualize the result, I will follow the same steps taken when visualizing the results for Queen contiguity-based neighbours.
plot(msia_map$geometry, border="lightgrey")
plot(msia_map_rook,
coords,
pch = 20,
cex = 0.5,
add = TRUE,
col= "blue")

At the first glance, it looks like the list of neighbours derived based on both Queen and Rook approaches look the same.
To find the different neighbours, I will use diffnb function to compare.
diff_nb <- diffnb(msia_map_queen, msia_map_rook)
Then, I will use similar approach to visualize the differences.
I will also color the differences in red colors.
plot(msia_map$geometry, border="lightgrey")
plot(diff_nb,
coords,
pch = 20,
cex = 0.5,
add = TRUE,
col= "red")

Based on the result, it seems like most of the neighbours derived are rather similar between Queen and Rook approaches.
That’s all for the day!
Thanks for reading the post until the end.
Feel free to contact me through email or LinkedIn if you have any suggestions on future topics to share.
Refer to this link for the blog disclaimer.
Till next time, happy learning!

Photo by Victor Freitas on Unsplash